#include <opencv2/imgcodecs.hpp>
#include <opencv2/imgproc.hpp>
#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>
#include <cstdint>

double line_detect(cv::InputOutputArray image);

int main(int argc, char *argv[])
{
	std::ios::sync_with_stdio(false);
	if (argc != 2)
	{
		std::cerr<< "Usage: angle input_file\n\n";
		return 1;
	}
	cv::Mat src = cv::imread(argv[1]);
	double result = line_detect(src);
	std::cout << result << "\n";
	return 0;
}

double line_detect(cv::InputOutputArray image)
{
	cv::Mat hsv, mask1, mask2, mask, edges, kernel = (cv::Mat_<uint8_t>(3, 3) << 1, 1, 1, 1, 1, 1, 1, 1, 1);
	cv::Scalar lowera(0, 0, 221), uppera(180, 30, 255);
	std::vector<cv::Vec4i> lines;
	int x1, y1, x2, y2;
	double result, total = 0;
	cv::cvtColor(image, hsv, cv::COLOR_BGR2HSV);
	cv::inRange(hsv, lowera, uppera, mask1);
	cv::morphologyEx(mask1, mask2, cv::MORPH_CLOSE, kernel);
	cv::morphologyEx(mask2, mask, cv::MORPH_OPEN, kernel);
	cv::Canny(mask, edges, 5, 150);
	cv::HoughLinesP(edges, lines, 1, CV_PI / 180, 40, 1, 100);
	for (auto line: lines)
	{
		x1 = line[0];
		y1 = line[1];
		x2 = line[2];
		y2 = line[3];
		cv::line(image, cv::Point(x1, y1), cv::Point(x2, y2), cv::Scalar(0, 0, 225), 2);
		if (x1 == x2) result = 90;
		else if (y1 == y2) result = 0;
		else result = atan((double)(y2 - y1) / (x2 - x1)) * 180 / CV_PI;
		total += abs(result);
	}
#ifdef DEBUG
	cv::imwrite("./tmp/tmp01.png", image);
#endif
	return total / lines.size();
}
